"""
Author        yongfa
Date          2022-07-18 16:24:41
LastEditTime  2022-07-21 14:09:13
LastEditors   yongfa
Description   缓存装饰器
"""


from flask import g, request
from urllib.parse import urlencode
from app.extensions import cache
from functools import wraps

sign_fields = ['accesskey_id', 'timestamp', 'signature', 'nonce']


def cached(timeout: int = 5 * 60, key: str = 'cached_{}_{}') -> callable:
    """缓存装饰器

    Args:
        timeout (int, optional): [缓存的秒数]. Defaults to 5*60.
        key (str, optional): [缓存的key的格式]. Defaults to 'cached_{}_{}'.

    Returns:
        callable: [description]
    """

    def decorator(func):
        @wraps(func)
        def decorated_function(*args, **kwargs):
            # 以 { key:value } 的形式存到内存
            query_args = dict(request.args.to_dict())
            body_args = request.get_json(silent=True) or {}
            req_args = dict(query_args, **body_args)

            suffix = urlencode([(k, req_args[k]) for k in sorted(req_args.keys())
                               if k not in sign_fields])
            cache_key = key.format(request.path, suffix)
            value = cache.get(cache_key)  # 获取
            if value is None:
                value = func(*args, **kwargs)
                cache.set(cache_key, value, timeout=timeout)  # 设置
            return value

        return decorated_function

    return decorator


def user_cached(timeout: int = 5 * 60, key: str = 'cached_{}_{}_{}') -> callable:
    """[缓存装饰器]

    Args:
        timeout (int, optional): [缓存的秒数]. Defaults to 5*60.
        key (str, optional): [缓存的key的格式]. Defaults to 'cached_{}_{}'.

    Returns:
        callable: [description]
    """

    def decorator(func):
        @wraps(func)
        def decorated_function(*args, **kwargs):
            # 以 { key:value } 的形式存到内存
            query_args = dict(request.args.to_dict())
            body_args = request.get_json(silent=True) or {}
            req_args = dict(query_args, **body_args)

            suffix = urlencode([(k, req_args[k]) for k in sorted(req_args.keys())])
            user_id = g.user_id if hasattr(g, 'user_id') else ''
            cache_key = key.format(request.path, suffix, user_id)
            value = cache.get(cache_key)  # 获取
            if value is None:
                value = func(*args, **kwargs)
                cache.set(cache_key, value, timeout=timeout)  # 设置
            return value

        return decorated_function

    return decorator
